<?php

namespace apiend\modules\statistic\models;

use Yii;
use common\helpers\ArrayHelper;
use yii\db\Query;
use yii\db\Expression;
use common\models\shop\ShopOrder;
use common\models\shop\ShopOrderGoods;
use common\models\shop\ShopOrderRefund;
use common\models\shop\ShopGoods;
use common\models\shop\ShopStore;

/**
 * 概况统计面板
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class OverviewStatsLogic extends OverviewStatsModel {

    /**
     * @inheritdoc
     */
    public function getBasics() {
        $cache = static::getCommonCache();
        $keyname = $this->getCacheKeyName(__FUNCTION__);
        $data = $cache->get($keyname);
        if ($data !== false) {
            return $data;
        }

        $query = ShopOrder::find()->alias('t');
        $query->andFilterWhere([
            't.store_id' => $this->store_id
        ]);
        $query->andWhere([
            'and',
            ['!=', 't.trade_id', 0],
            ['>', 't.pay_time', 0],
        ]);
        $query->andFilterDuration('t.created_at', $this->beginTime, $this->endTime);

        $refundQuery = clone $query;

        $refundQuery->joinWith('refunds refunds');
        $refundQuery->andWhere([
            'or',
            ['refunds.id' => null],
            [
                'and',
                ['refunds.deleted_at' => 0],
                ['>', 'refunds.status', ShopOrderRefund::STATUS_AUDIT],
                ['>', 'refunds.refund_pay', 0],
                ['>', 'refunds.refund_time', 0],
            ]
        ]);
        $refundQuery->select([
            't.id',
            't.user_id',
            'pay' => new Expression('`t`.`pay`- IFNULL(SUM(`refunds`.`refund_pay`),0)'),
        ]);
        $refundQuery->having([
            '>', 'pay', 0
        ]);
        $refundQuery->groupBy('t.id');

        $refundQuery->debug();
        $orders = $refundQuery->asArray()->all();
        //有效单统计
        $payAmount = ArrayHelper::sum($orders, 'pay');
        $counts = count($orders);
        $orderAmountAverage = round($counts ? $payAmount / $counts : 0, 2);
        //有效单会员数
        $orderUserQuery = (new Query())->from(['order' => $refundQuery])->groupBy('order.user_id');
        $orderUsers = $orderUserQuery->count();
        //有效单商品统计
        $orderGoodsQuery = (new Query())->from(['goods' => ShopOrderGoods::tableName()])->innerJoin([
            'order' => $refundQuery
        ], 'order.id = goods.order_id');
        $orderGoods = $orderGoodsQuery->select([
            'numbers' => 'sum(goods.goods_number)',
            'average' => 'avg(goods.goods_price)',
        ])->one();
        $orderGoodsNumbers = ArrayHelper::getValue($orderGoods, 'numbers');
        $orderGoodsAverage = round(ArrayHelper::getValue($orderGoods, 'average'), 2);
        //
        $newStores = ShopStore::find()->andFilterDuration('created_at', $this->beginTime, $this->endTime)->count();
        $newSkus = ShopGoods::find()->andFilterDuration('created_at', $this->beginTime, $this->endTime)->count();

        $goodsQuery = ShopGoods::find()->alias('t')->innerJoinWith('product product')->andWhere([
            'product.deleted_at' => 0,
            'product.status' => ShopGoods::STATUS_ACTIVE,
        ]);
        $skus = $goodsQuery->count();
        $spus = $goodsQuery->groupBy('t.product_id')->count();

        $result = [
            'debug' => $orderGoods,
            'amount' => $payAmount,
            'counts' => $counts,
            'orderGoodsNumbers' => $orderGoodsNumbers,
            'orderGoodsAverage' => $orderGoodsAverage,
            'orderUsers' => $orderUsers,
            'orderAmountAverage' => $orderAmountAverage,
            'newSkus' => $newSkus,
            'newStores' => $newStores,
            'skus' => $skus,
            'spus' => $spus,
        ];
        if ($cache) {
            Yii::error([
                $keyname,
                $result,
            ], __METHOD__);
            $cache->set($keyname, $result, 600);
        }
        return $result;
    }

    /**
     * @inheritdoc
     */
    public function getStores() {
        $model = new RankStoreSearch();
        $model->load($this->attributes, '');
        return $model->search();
    }

    /**
     * @inheritdoc
     */
    public function getGoods() {
        $model = new RankGoodsSearch();
        $model->load($this->attributes, '');
        return $model->search();
    }

    /**
     * @inheritdoc
     */
    public function fields() {
        return [
            'basics',
            'stores',
            'goods',
            'beginTime' => function() {
                return date('Y-m-d H:i:s', $this->beginTime);
            },
            'endTime' => function() {
                return date('Y-m-d H:i:s', $this->endTime);
            },
        ];
    }

}
